
from urllib.parse import urljoin
import requests


class OpenEulerCVEClient:
    """
    OpenEuler CVE 客户端类。
    """

    def __init__(self): ...

    def normalise(self, cve_data, product_package):
        """
        对数据进行规范化处理。

        Args:
            data (dict): 待处理的数据。

        Returns:
            dict: 处理后的数据。
        """
        # ret = {}
        result = cve_data.get("result")

        return {
            "cve_id": result["cveId"],
            "summary": result["summary"],
            "cvsssCoreOE": result["cvsssCoreOE"],
            "product_package": product_package["result"],
        }

    def get_data(self, cve_id, package_name):
        cve_info = self.get_by_cve_id_and_package_name(cve_id, package_name)
        if not cve_info["success"]:
            raise RuntimeError("获取 CVE 描述失败。")

        procudt_package_list = self.get_cve_product_package_list(cve_id, package_name)
        if not procudt_package_list["success"]:
            raise RuntimeError("获取 CVE 产品包列表失败。")

        data = self.normalise(cve_info, procudt_package_list)
        return data

    def get_cve_product_package_list(self, cve_id, package_name):
        """
        获取指定 CVE ID 和软件包名称的 CVE 产品包列表。

        Args:
            cve_id (str): CVE ID，如 CVE-2024-29018。
            package_name (str): 软件包名称，如 docker。

        Returns:
            list: 包含 CVE 产品包的列表。
        """
        baseurl = "https://www.openeuler.org/api-cve/cve-security-notice-server/cvedatabase/getCVEProductPackageList"
        query_params = {"cveId": cve_id, "packageName": package_name}
        resp = requests.get(baseurl, params=query_params)
        resp.raise_for_status()
        return resp.json()

    def get_by_cve_id_and_package_name(self, cve_id, package_name):
        """
        获取指定 CVE ID 和软件包名称的 CVE 描述。

        Args:
            cve_id (str): CVE ID，如 CVE-2024-29018。
            package_name (str): 软件包名称，如 docker。

        Returns:
            str: CVE 描述。
        """
        baseurl = "https://www.openeuler.org/api-cve/cve-security-notice-server/cvedatabase/getByCveIdAndPackageName"
        query_params = {"cveId": cve_id, "packageName": package_name}
        resp = requests.get(baseurl, params=query_params)
        resp.raise_for_status()
        return resp.json()


class OpenAnolisCVEClient:
    def normalise(self, cve_data, cve_id):
        """
        对数据进行规范化处理。

        Args:
            data (dict): 待处理数据。

        Returns:
            dict: 处理后的数据。
        """
        if cve_data["status"]["code"] == 404:
            return {
                "cve_id": cve_id,
                "summary": "",
                "cvsssCoreOE": "",
                "product_package": [],
                "msg": "Anolis OS中不存在这个CVE",
            }
        data = cve_data.get("data")

        product_package = [
            {
                "packageName": item["rpm_name"],
                "status": item["rpm_status"],
                "productName": item["name_version"],
                "releaseTime": item["publish_date"],
                "updateTime": "",
            }
            for item in data["product_package"]["data"]
        ]

        return {
            "cve_id": data["cve_id"],
            "summary": data["abstract"],
            "cvsssCoreOE": data["score"],
            "affected_packages": data["affected_packages"],
            "product_package": product_package,
        }

    def get_data(self, cve_id: str, package_name: str):
        cve_data = self.get_cve(cve_id)
        return self.normalise(cve_data, cve_id)

    def get_cve(self, cve_id: str):
        # ending with / is necessary
        baseurl = (
            urljoin("https://anas.openanolis.cn/api/portal/v1/cves/", cve_id) + "/"
        )
        query_params = {"page_size": 100, "page_num": 1}
        resp = requests.get(baseurl, params=query_params)
        resp.raise_for_status()
        return resp.json()
